<?php

declare(strict_types=1);

namespace app\exception;

use Dsxwk\Framework\Annotation\Enums\interface\ErrCodeInterface;
use Dsxwk\Framework\Utils\Exception\CodeException;
use support\Log;
use Throwable;
use Webman\Exception\ExceptionHandler;
use Webman\Http\Response;

class Handle extends ExceptionHandler
{
    protected int    $code = 500;

    protected string $msg  = '';

    protected array  $data = [];

    /**
     * 不需要报告的异常类
     *
     * @var array
     */
    public $dontReport = [
        // ...
    ];

    /**
     * 报告异常
     *
     * @param Throwable $exception
     *
     * @return void
     */
    public function report(Throwable $exception): void
    {
        Log::error((string)$exception);
    }

    /**
     * 异常处理
     *
     * @param           $request
     * @param Throwable $exception
     *
     * @return Response
     */
    public function render($request, Throwable $exception): Response
    {
        $debug     = config('app.debug');
        $this->msg = $exception->getMessage();

        if ($exception instanceof ErrCodeInterface) {
            $this->code = $exception->getErrCode();
            $this->msg  = $exception->getErrMsg();
        }

        if ($exception instanceof CodeException) {
            $this->code = $exception->getCode();
            $this->msg  = $exception->getMessage();
            $this->data = $exception->getData();
        }

        $result = [
            'code' => $this->code,
            'msg'  => $this->msg,
            'data' => []
        ];

        if ($debug) {
            $result['data'] = array_merge(
                $this->data,
                [
                    'exception' => get_class($exception),
                    'file'      => $exception->getFile(),
                    'line'      => $exception->getLine(),
                    'trace'     => explode("\n", $exception->getTraceAsString()),
                ]
            );
        }

        return response(json_encode($result, JSON_UNESCAPED_UNICODE));
    }
}